#pragma once
#include "Packet.h"

namespace Protocol{
#pragma pack(push)
#pragma pack(1)

const static uint32 DHCP_SHIFT=16;
const static uint32 DHCP_MASK=~((1<<DHCP_SHIFT)-1);

struct Message
{
	unsigned char type;
	unsigned char sequence;
	unsigned char padd[2];

	const static unsigned char LOGIN=0;
	const static unsigned char LOGIN_REPLY=1;
	const static unsigned char KEEPALIVE=2;
	const static unsigned char ROUTE=3;
	const static unsigned char INFORMATION=4;
	const static unsigned char ACKNOWLEDGE=5;
};

struct Acknowledge : public Message
{

};

struct KeepAlive : public Message
{
	unsigned int vir_ip;
	mac_addr mac;
};

#pragma warning(disable: 4200)
struct Information : public Message
{
	size_t online_players;
	struct
	{
		unsigned int ip;
		mac_addr mac;
		unsigned short port;
	}peer[0];

	size_t bytes()
	{
		return sizeof(online_players)+sizeof(peer[0])*online_players;
	}

	//the upper bound, depends on the udp packet size
	const static size_t max_size=85;
};

struct Login : public Message
{
	unsigned int ver;
	const static unsigned char VERSION=1;
	const static unsigned char COMPATIBLE_VERSION=0;
};

struct LoginReply : public Message
{
	unsigned int code;
	unsigned int vir_ip;		//virtual ip
	unsigned int vir_mask;		//virtual subnet mask
	const static unsigned int Ok=0;
	const static unsigned int Old=1;
	const static unsigned int TooOld=2;
};

struct Route : public Message
{
	//unsigned short size, src_port;
	//unsigned int src_ip;
	//bool routed;
	const static int max=64*1024+100;
	union
	{
		Packet headers;		// mac,ip,udp header
		char padd[max];
	};
};

#pragma warning(disable: 4200)
struct AllPeers : public Message
{
	unsigned short flag;
	unsigned short size;
	struct
	{
		unsigned int ip;
		mac_addr mac;
		unsigned short port;
	}peer[0];
	
	//the upper bound, depends on the udp packet size
	const static unsigned short max_size=85;
};

#pragma pack(pop)
};//namespace Protocol

